﻿/****************************** Module Header ******************************\
 * Module Name:  FileUploadGroup.cs
 * Module Version:  1.0.0 (2012-1-13)
 * Copyright (c) AnyEB.Com (14507247@qq.com)
 * 
 * This componse is use for upload files.
 * 
 * This source is subject to the GPL License.
 * See http://www.gnu.org/licenses/gpl.html.
 * All other rights reserved.
 * 
 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace UCF.Core.Web.CustomControls
{
    /// <summary>
    /// 文件上传组控件
    /// </summary>
    [DefaultProperty("Text")]
    [ToolboxData("<{0}:FileUploadGroup runat=server></{0}:FileUploadGroup>")]
    public class FileUploadGroup : CompositeControl
    {
        private Panel panel;
        private Button btnAddFile;
        private Button btnRemoveFile;
        private IList<String> files;
        /// <summary>
        /// 获取或设置最多文件上传数量,默认是5个
        /// </summary>
        public int MaxNumber { get; set; }
        /// <summary>
        /// 获取或设置是否显示序号
        /// </summary>
        public bool ShowNumber { get; set; }
        /// <summary>
        /// 获取或设置上传控件组中的所有文件列表
        /// </summary>
        public IList<String> Files { get; set; }
        /// <summary>
        /// 获取或设置添加控件按钮的文本
        /// </summary>
        public string ButtonTextAdd
        {
            get
            {
                EnsureChildControls();
                return this.btnAddFile.Text;
            }
            set
            {
                EnsureChildControls();
                this.btnAddFile.Text = value;
            }
        }
        /// <summary>
        /// 获取或设置移除控件按钮的文本
        /// </summary>
        public string ButtonTextRemove
        {
            get
            {
                EnsureChildControls();
                return this.btnRemoveFile.Text;
            }
            set
            {
                EnsureChildControls();
                this.btnRemoveFile.Text = value;
            }
        }
        /// <summary>
        /// 创建子控件
        /// </summary>
        protected override void CreateChildControls()
        {
            if (this.ChildControlsCreated) return;
            if(this.Files==null) this.Files=new List<String>();
            if(this.FetchViewState("files")==null) this.KeepViewState("files",this.Files);
            this.files = (IList<String>)this.FetchViewState("files");
            if (this.FetchViewState("filescount") == null) this.KeepViewState("filescount", 1);
            if (this.MaxNumber == 0) this.MaxNumber = 5;
            int intNumber = (Int32)this.FetchViewState("filescount");

            // create controls
            this.panel = new Panel();
            this.panel.ID = this.ID;

            // init fileupload controls
            LinkButton lnkButton;
            HtmlGenericControl oDiv;
            HtmlGenericControl oSpan;
            Image imgPicture;
            String strExtend="";
            String strFile="";
            int intFilesCount = this.files.Count;
            while (intFilesCount > 0)
            {
                strFile = this.files[intFilesCount - 1];
                oDiv = new HtmlGenericControl("div");
                lnkButton = new LinkButton();
                lnkButton.Text = " x ";
                lnkButton.Attributes["file"] = strFile;
                lnkButton.Click += lnkDeleteButton_Click;
                oDiv.Controls.Add(lnkButton);
                strExtend = System.IO.Path.GetExtension(strFile).ToLower();
                switch (strExtend)
                {
                    case ".gif":
                    case ".png":
                    case ".jpg":
                    case ".bmp":
                        imgPicture = new Image();
                        imgPicture.ImageUrl = strFile;
                        imgPicture.Width = 60;
                        imgPicture.Height = 60;
                        imgPicture.AlternateText = System.IO.Path.GetFileName(strFile);
                        oDiv.Controls.Add(imgPicture);
                        break;
                    default:
                        oSpan = new HtmlGenericControl("span");
                        oSpan.InnerHtml = System.IO.Path.GetFileName(strFile);
                        oDiv.Controls.Add(oSpan);
                        break;
                }
                this.panel.Controls.AddAt(0, oDiv);
                intFilesCount--; 
            }
            int counter = 1;
            while (intNumber > 0)
            {
                oDiv = new HtmlGenericControl("div");
                if (this.ShowNumber)
                {
                    oSpan = new HtmlGenericControl("span");
                    oSpan.InnerText = string.Format("{0}.", counter);
                    oDiv.Controls.Add(oSpan);
                }
                oDiv.Controls.Add(new FileUpload());
                this.panel.Controls.Add(oDiv);
                intNumber--;
                counter++;
            }
            this.btnAddFile = new Button();
            this.btnRemoveFile = new Button();
            this.btnAddFile.Click += btnAddFile_Click;
            this.btnRemoveFile.Click += btnRemoveFile_Click;
            this.btnAddFile.Text = "添加";
            this.btnRemoveFile.Text = "移除";
            this.panel.Controls.Add(this.btnAddFile);
            this.panel.Controls.Add(this.btnRemoveFile);
            this.Controls.Add(this.panel);
        }
        /// <summary>
        /// 删除文件按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lnkDeleteButton_Click(object sender, EventArgs e)
        {
            LinkButton lnkButton = (LinkButton)sender;
            String strFile = lnkButton.Attributes["file"];
            if (strFile == null || strFile.Length == 0) return;
            IList<String> lstFiles =(IList<String>) this.FetchViewState("files");
            lstFiles.Remove(strFile);
            this.KeepViewState("files", lstFiles);
            strFile = this.Page.Server.MapPath(strFile);
            System.IO.File.Delete(strFile);
            this.RecreateChildControls();
        }
        /// <summary>
        /// 添加上传文件控件按钮的点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnAddFile_Click(object sender, EventArgs e)
        {
            int intCount =(Int32) this.FetchViewState("filescount");
            IList<String> lstFiles = (IList<String>)this.FetchViewState("files");
            int intFilesCount = (lstFiles == null) ? 0 : lstFiles.Count;
            if (intCount + intFilesCount >= this.MaxNumber) return;
            intCount++;
            this.KeepViewState("filescount",intCount);
            this.RecreateChildControls();
        }
        /// <summary>
        /// 移除上传文件控件按钮的点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnRemoveFile_Click(object sender, EventArgs e)
        {
            int intCount =(Int32) this.FetchViewState("filescount");
            if (intCount < 2) return;
            intCount--;
            this.KeepViewState("filescount",intCount);
            this.RecreateChildControls();
        }
        /// <summary>
        /// 重绘控件外观
        /// </summary>
        /// <param name="writer"></param>
        protected override void Render(HtmlTextWriter writer)
        {
            foreach (Control oControl in this.Controls)
            {
                oControl.RenderControl(writer);
            }
        }
        /// <summary>
        /// 保存ViewState数据
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        private void KeepViewState(string name, object value)
        {
            ViewState[name] = value;
        }
        /// <summary>
        /// 获取ViewState数据
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        private object FetchViewState(string name)
        {
            return ViewState[name];
        }
        /// <summary>
        /// 保存上传控件组中的所有文件
        /// </summary>
        /// <param name="uploadFolder"></param>
        /// <param name="namedByTimeStamp"></param>
        /// <returns></returns>
        public IList<String> SaveFiles(string uploadFolder, bool namedByTimeStamp)
        {
            String strFileName = "";
            IList<String> lstFiles=new List<String>();
            lstFiles.AppendR((IList<String>) this.FetchViewState("files"));
            Random oRnd = new Random();
            foreach(String sFile in this.Page.Request.Files.AllKeys)
            {
                strFileName = this.Page.Request.Files[sFile].FileName;
                if (this.Page.Request.Files[sFile].ContentLength == 0) continue;
                if (namedByTimeStamp)
                {
                    strFileName = System.IO.Path.GetExtension(strFileName);
                    strFileName = DateTime.Now.ToString("yyyyMMddHHmmss")+oRnd.Next(100,999).ToString() + strFileName;
                }
                strFileName = uploadFolder.WrapString("", "/") + strFileName;
                lstFiles.Add(strFileName);
                this.Page.Request.Files[sFile].SaveAs(this.Page.Server.MapPath(strFileName));
            }
            return lstFiles;
        }
    }
}
